package cn.wmw.xyy.service.impl;

import cn.wmw.result.JsonResult;
import cn.wmw.xyy.VerifyConstant.VerifyConst;
import cn.wmw.xyy.bo.RedisSmsVerifyBo;
import cn.wmw.xyy.domain.*;
import cn.wmw.xyy.dto.RegisterPhoneDto;
import cn.wmw.xyy.exception.GlobalException;
import cn.wmw.xyy.exception.GlobalExceptionEnum;
import cn.wmw.xyy.feign.LoginFeignClient;
import cn.wmw.xyy.feign.MessageSmsFeignClient;
import cn.wmw.xyy.feign.UserCodeFeignClient;
import cn.wmw.xyy.mapper.UserMapper;
import cn.wmw.xyy.service.IUserAccountService;
import cn.wmw.xyy.service.IUserBaseInfoService;
import cn.wmw.xyy.service.IUserService;
import cn.wmw.xyy.utils.AssertUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;


import java.util.Date;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author wmw
 * @since 2022-12-27
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Autowired
    private LoginFeignClient loginFeignClient;

    @Autowired
    private MessageSmsFeignClient messageSmsFeignClient;

    @Autowired
    private IUserAccountService userAccountService;

    @Autowired
    private IUserBaseInfoService userBaseInfoService;

    @Autowired
    private UserCodeFeignClient userCodeFeignClient;


    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void register(RegisterPhoneDto dto) {
        Date date = new Date();
        String phone = dto.getMobile();
        String smsCode = dto.getSmsCode();
        Integer regChannel = dto.getRegChannel();
        String code = "";

        JsonResult jsonResult = userCodeFeignClient.linkCode(dto.getLinkCode());
        if(!jsonResult.isSuccess()){
            throw new GlobalException(GlobalExceptionEnum.ERROR);
        }
        Object o = redisTemplate.opsForValue().get(String.format(VerifyConst.REDIS_REGISTER_PHONE, phone));
        AssertUtil.isNotNull(o, GlobalExceptionEnum.USER_CODE_NOT_EXISTENT);
        RedisSmsVerifyBo redisUserVerifyBo = (RedisSmsVerifyBo) o;
        code = redisUserVerifyBo.getCode();
        AssertUtil.isEqualsIgnoreCase(smsCode,code,GlobalExceptionEnum.USER_CODE_ERROR);
        selectByPhone(phone);
        Long loginId = saveLogin(dto);
        Long userId = saveUser(phone, loginId);
        UserAccount(date, phone, userId);
        UserBaseInfo(regChannel, userId);
    }

    private void UserBaseInfo(Integer regChannel, Long userId) {
        UserBaseInfo userBaseInfo = new UserBaseInfo();
        userBaseInfo.setCreateTime(new Date().getTime());
        userBaseInfo.setId(userId);
        userBaseInfo.setRegChannel(regChannel);
        userBaseInfoService.insert(userBaseInfo);
    }

    private void UserAccount(Date date, String phone, Long userId) {
        //初始化账户信息
        UserAccount userAccount = new UserAccount();
        userAccount.setId(userId);
        userAccount.setCreateTime(new Date().getTime());
        userAccount.setPassword("123456");
        String context = "您的初始用户名为:"+ phone +"，您的初始密码为:123456";
        saveMessage(date, context);
        //6.发送短信验证码
        log.info(context);
        userAccountService.insert(userAccount);
    }

    private void saveMessage(Date date, String context) {
        MessageSms messageSms = new MessageSms();
        messageSms.setTitle("注册初始化账户信息");
        messageSms.setContent(context);
        String ip = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getRemoteAddr();
        messageSms.setIp(ip);
        messageSms.setSendTime(date);
        messageSmsFeignClient.saveOrUpdate(messageSms);
    }

    private Long saveUser(String phone, Long loginId) {
        User user = new User();
        user.setCreateTime(new Date().getTime());
        user.setPhone(phone);
        user.setNickName(phone);
        user.setLoginId(loginId);
        insert(user);
        Long userId = user.getId();
        return userId;
    }

    private Long saveLogin(RegisterPhoneDto dto) {
        //存登录信息
        Login login = new Login();
        login.setUsername(dto.getMobile());
        login.setPassword(dto.getPassword());
        login.setType(Login.HOME_TYPE);
        login.setEnabled(true);
        login.setAccountNonExpired(true);
        login.setCredentialsNonExpired(true);
        login.setAccountNonLocked(true);
        JsonResult jsonResult = loginFeignClient.saveOrUpdate(login);
        AssertUtil.isTrue(jsonResult.isSuccess(), GlobalExceptionEnum.ERROR);
        Object data = jsonResult.getData();
        AssertUtil.isNotNull(data, GlobalExceptionEnum.ERROR);
        Long loginId = Long.valueOf(data.toString());
        return loginId;
    }

    private void selectByPhone(String phone) {
        //查询手机号是否注册
        Wrapper<User> wrapper = new EntityWrapper<>();
        wrapper.eq("phone", phone);
        User user = selectOne(wrapper);
        AssertUtil.isNull(user,GlobalExceptionEnum.USER_IS_NOT_NULL_ERROR);
    }
}
